package com.joey.protocol;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonIOException;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSyntaxException;
import com.joey.base.BaseModel;
import com.joey.base.OnLoadingListener;
import com.joey.base.util.LogUtils;

import org.json.JSONException;

import java.io.IOException;
import java.io.Serializable;

import okhttp3.Call;
import okhttp3.Response;

/**
 * Created by Joey on 2018/3/29.
 * <p>
 * {"code":"","result":"","message":""}
 */

public abstract class JSONResponseListener<T extends JsonElement> extends NetResponseListener {


    static String msgK = NetClientConfig.I.getJsonFormat().msgKey;
    static String statusK = NetClientConfig.I.getJsonFormat().statusKey;
    static String resultK = NetClientConfig.I.getJsonFormat().resultKey;

    private final int MES_SINK_PROGRESS = 0x003;

    public JSONResponseListener(OnLoadingListener listener) {
        this();
        setOnLoadingListener(listener);
    }

    public String getTestResponse() {
        return "";
    }

    public JSONResponseListener() {
        mainHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case MES_SINK_PROGRESS:
                        removeMessages(MES_SINK_PROGRESS);
                        if (msg.getData() == null) {
                            return;
                        }
                        long total = msg.getData().getLong("total");
                        long progress = msg.getData().getLong("progress");
                        int index = msg.getData().getInt("index");
                        mainHandler.removeMessages(MES_SINK_PROGRESS);
                        onSink(total, progress, progress * 100.0f / total, index);
                        break;
                }
            }
        };
    }

    public abstract void onResponse(T result, ResponseError error) throws JsonIOException;

    @Override
    final public void onSuccess(Call call, Response response) {
        try {
            final String s = response.body().string();
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    convert(s);
                }
            });
        } catch (IOException e) {
            ResponseError error = new ResponseError(ResponseError.ERRPR_BY_SERVER, e.getMessage());
            onError(call, error);
        }
    }

    @Override
    final public void onError(Call call, final ResponseError error) {
        LogUtils.e("error = " + error.getMessage());
        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                LogUtils.e("error = " + error.toString());
                // 表示正在测试
                if (isDebug()) {
                    convert(getTestResponse());
                    return;
                }
                handleError(error);

            }
        });
    }

    public void convert(String s) {
        Gson gson = new GsonBuilder().create();
        error = new ResponseError(ResponseError.ERRPR_BY_SERVER, s);
        try {
            LogUtils.i("response = " + s);
            JsonObject object = gson.fromJson(s, JsonObject.class);
            String msg = object.get(msgK).getAsString();
            String code = object.get(statusK).getAsString();
            error.setMessage(msg);
            error.setStatus(code);
            try {
                T json = (T) object.get(resultK);
                error.result = object.get(resultK);
                if (!ResponseError.ERROR_SUCCESS.equals(code)) {
                    handleError(error);
                    return;
                }
                onResponse(json, error);
            } catch (JsonSyntaxException e) {
                error.setStatus(ResponseError.ERROR_BY_PARSE);
                handleError(error);
            }

        } catch (JsonSyntaxException ie) {
            error.setMessage("服务器接口出错啦！");
            error.setResult(new JsonObject());
            error.setStatus(ResponseError.ERRPR_BY_SERVER);
            handleError(error);
        } catch (Exception ee) {
            error.setMessage(ee.getMessage());
            error.setResult(new JsonObject());
            error.setStatus(ResponseError.ERROR_UN_KNOWN);
            handleError(error);
        }
    }

    protected void handleError(ResponseError error) {
        try {
            // 统一的错误处理方法
            if (NetClientConfig.I.getListener() != null) {
                // 返回true的话进行拦截，不再走自定义方法
                if (NetClientConfig.I.getListener().onError(error)) {
                    return;
                }
            }
            onError(error);
        } catch (JsonSyntaxException e2) {
            e2.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public final void onSink(long total, long sink, int index, boolean done) {
        long progress = total - sink;
        Message msg = mainHandler.obtainMessage(MES_SINK_PROGRESS);
        msg.what = MES_SINK_PROGRESS;
        Bundle bundle = new Bundle();
        bundle.putLong("total", total);
        bundle.putLong("progress", progress);
        bundle.putInt("index", index);
        msg.setData(bundle);
        mainHandler.sendMessageDelayed(msg, 50);
    }

    public void onSink(long total, long progress, float percent, int index) {

    }

}
